import $API from '@/api'
import LocationLevelName from './LocationLevelName'

// 由ParseGEORawResult解析的我们想要的数据
export default class LocationLngLatCode {
  // 经度
  longitude: number

  // 纬度
  latitude: number

  // 省份编码
  provinceCode: number

  // 城市编码
  cityCode: number

  // 区县编码
  districtCode: number

  // 简单地址名
  addressLabel: string

  // 详细地址名
  locationLevelName: LocationLevelName

  /**
   * 定位获取用户位置
   */
  public async requestLocation(): Promise<Boolean> {
    const that = this
    return new Promise((resolve, reject) => {
      uni.authorize({
        scope: 'scope.userLocation',
        success: (success) => {
          uni.getLocation({
            isHighAccuracy: true,
            type: 'gcj02',
            success: async function (res) {
              that.longitude = res.longitude
              that.latitude = res.latitude

              await that.refreshLocationDetail()
              console.log('获取位置成功', that)
              resolve(true)
            },
            fail: (err) => {
              reject(err)
            }
          })
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }

  /**
   * 用户手动选择位置
   */
  public requestLocationForManual(): Promise<Boolean> {
    const that = this
    return new Promise<Boolean>((resolve, reject) => {
      uni.chooseLocation({
        success: async ({ name, latitude, longitude }) => {
          that.latitude = latitude
          that.longitude = longitude
          await that.refreshLocationDetail()
          that.addressLabel = name

          // (!!为什么是请求到lat\lng且code才请求数据，因为更快!!)
          resolve(true)
        },
        fail: () => {
          reject()
        }
      })
    })
  }

  /**
   * 根据坐标获取其它位置信息
   */
  private async refreshLocationDetail(): Promise<LocationLevelName> {
    if (this.longitude == null || this.latitude == null) {
      throw new Error('经纬度信息不完整，无法获取位置信息')
    }
    const { provinceCode, provinceName, cityCode, cityName, districtCode, districtName, detailAddress } =
      await $API.thirdParty.parseGEO(this.longitude, this.latitude)

    this.provinceCode = provinceCode
    this.cityCode = cityCode
    this.districtCode = districtCode

    this.addressLabel = detailAddress || `${districtName}${cityName}${provinceName}`
    this.locationLevelName = new LocationLevelName(provinceName, cityName, districtName, detailAddress)
    return this.locationLevelName
  }
}
